#include "rnet.h"
#include "rlock.h"
#include "com_service.h"
#include "com_read_task.h"
#include <json/reader.h>
#include <json/json.h>
using namespace	Json ;


com_service::com_service() 
{
	pthread_mutex_init(&m_task.m_lock, NULL) ;
}

com_service::~com_service() 
{
	pthread_mutex_destroy(&m_task.m_lock) ;
	m_task.clear();
}

bool com_service::start()
{
	if ( !connect() )
	{
		rlog << "connect(" << com_device << ") error"  << endl ;
		return false ;
	}

	rthreadpool::_instance().add_task(new com_read_task(m_task));
	return do_get_args();
}

bool com_service::connect()
{
	if ( m_task.is_online() )
		return true ;

	rmutex rlock(m_task.m_lock);
	
	int fd = open( com_device, O_RDWR | O_NOCTTY | O_NONBLOCK );         //| O_NOCTTY | O_NDELAY    
	if ( fd < 0 )    
	{
		rlog << "open(" << com_device << ") error : " << strerror(errno)  << endl ;
		return	false ;
	}

	struct termios option = {};
	memset(&option, 0x00, sizeof (option));
	cfmakeraw (&option);
	option.c_cflag |= com_baudrate | CLOCAL | CREAD; 
	option.c_cflag |= CS8;
	option.c_cflag &= ~PARENB;
	option.c_cflag &= ~CSTOPB ;
	option.c_oflag = 0;
	option.c_lflag |= 0;
	option.c_oflag &= ~OPOST;
	option.c_cc[VTIME] = 1; 
	option.c_cc[VMIN] = 1;
	tcflush (fd, TCIFLUSH);
	if ( tcsetattr(fd,TCSANOW,&option) < 0 )
	{
		rlog << "tcsetattr(" << com_device << ") error : " << strerror(errno)  << endl ;
		close(fd);
		return	false ;
	}

	m_task.mi_fd = fd ;

	return true ;
}

bool com_service::do_get_args()
{
	vector<unsigned char> v_data;
	v_data.push_back(0x83);
	v_data.push_back(0x00);

	if ( write(v_data) < 0 )
	{
		rlog << "com_service.write() error" << endl ;
		return false ;
	}

	return true ;
}

bool com_service::write(const vector<unsigned char>& v_data)
{
	if ( !connect() )
	{
		rlog << "connect(" << com_device << ") error"  << endl ;
		return false ;
	}
		
	rmutex rlock(m_task.m_lock);

	if( m_task.mi_fd == - 1)
	{
		rlog << "device(" << com_device << ") offline"  << endl ;
		return false ;
	}
	
	vector<unsigned char> v_send_data;
	v_send_data.push_back(0x69);
	int i_length= 1+2+(int)v_data.size()+1;
	v_send_data.push_back((unsigned char)i_length) ;
	v_send_data.push_back(0x00);
	v_send_data.push_back(0x00);
	v_send_data.insert(v_send_data.end(), v_data.begin(), v_data.end()) ;
	
	int i_cs = i_length+0x00+0x00;
	for( int i= 0 ; i < (int)v_data.size(); i++ )
		i_cs += v_data[i];		
	v_send_data.push_back((unsigned char)(i_cs&0xff));

	v_send_data.push_back(0x43) ;		
	
	if ( ::write( m_task.mi_fd, &v_send_data[0], (int)v_send_data.size() ) < 0 )
	{
		rlog << "write(" << com_device << ") error : " << strerror( errno )  << endl ;
		return	false ;
	}

	rlog << "write com(" << com_device << ")" << endl ;
	for( int i = 0 ; i < (int)v_send_data.size() ; i++ )
		printf( "0x%02x, ", v_send_data[i] ) ;
	cout << endl ;
	
	return true ;
}

